package judesart.app.repository;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import judesart.app.domain.Artwork;
import judesart.app.domain.ArtworkPhoto;
import judesart.app.domain.Image;
import judesart.app.shared.ValidationException;
import judesart.app.validation.AppValidator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class ArtworkDAOImpl implements ArtworkDAO {
    private final static Log LOGGER = LogFactory.getLog(ArtworkDAOImpl.class);

    @PersistenceContext
    private EntityManager entityManager;

    @Inject
    private AppValidator validator;

    @Inject
    private ImageDAO imageDAO;

    @Inject
    private ProjectDAO projectDAO;

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Artwork createArtwork(Artwork artwork) throws ValidationException {
        validator.validate(artwork);
        entityManager.persist(artwork);
        entityManager.flush();
        return artwork;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Artwork updateArtwork(Artwork artwork) throws ValidationException {
        validator.validate(artwork);
        artwork = entityManager.merge(artwork);
        entityManager.flush();
        return artwork;
    }

    @Override
    public int countArtworks(Long artistId) {
        return (Integer) entityManager.createNamedQuery(
                "Artwork.countByArtistId").setParameter("artistId", artistId).getSingleResult();
    }

    @SuppressWarnings("unchecked")
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public List<Artwork> findArtworks(Long artistId, int startAt,
            int maxElements) {
        List<Artwork> result = entityManager.createNamedQuery(
                "Artwork.findByArtistId").setParameter("artistId", artistId).setFirstResult(
                startAt).setMaxResults(maxElements).getResultList();
        for (Artwork artwork : result) {
            for (ArtworkPhoto photo : artwork.getPhotos()) {

            }
        }
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Long> findArtworkIds(Long artistId) {
        return entityManager.createNamedQuery("Artwork.findIdsByArtistId").setParameter(
                "artistId", artistId).getResultList();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Artwork findArtworkById(Long artworkId) {
        Artwork artwork = entityManager.find(Artwork.class, artworkId);
        for (ArtworkPhoto photo : artwork.getPhotos()) {

        }
        return artwork;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteArtwork(Long artworkId) {
        Artwork artwork = entityManager.find(Artwork.class, artworkId);
        entityManager.remove(artwork);
        entityManager.flush();
        if (artwork.getPhotos() != null) {
            for (ArtworkPhoto photo : artwork.getPhotos()) {
                imageDAO.deleteImage(photo.getImageId());
            }
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Artwork addImageToArtwork(Artwork artwork, String fileName,
            String blobKey) {
        Image image = new Image();
        image.setBlobKey(blobKey);
        image.setName(fileName);
        image = imageDAO.createImage(image);
        artwork = entityManager.merge(artwork);
        ArtworkPhoto photo = new ArtworkPhoto();
        photo.setArtwork(artwork);
        photo.setImageId(image.getId());
        if (artwork.getPhotos() == null) {
            artwork.setPhotos(new ArrayList<ArtworkPhoto>());
        }
        artwork.getPhotos().add(photo);
        entityManager.flush();
        return artwork;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Artwork deleteImageFromArtwork(Artwork artwork, Long photoId) {
        Image image = imageDAO.deleteImage(photoId);
        if (image != null) {
            artwork = entityManager.merge(artwork);
            List<ArtworkPhoto> photos = artwork.getPhotos();
            ArtworkPhoto found = null;
            for (ArtworkPhoto photo : photos) {
                if (photo.getImageId().equals(photoId)) {
                    found = photo;
                    break;
                }
            }
            if (found != null) {
                artwork.getPhotos().remove(found);
            }
            entityManager.flush();
        }
        return artwork;
    }
}
